package com.hiss.basic.system.service;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.hiss.basic.client.system.ISysDictItemService;
import com.hiss.basic.client.system.ISysDictService;
import com.hiss.basic.model.system.domain.SysDictDomain;
import com.hiss.basic.model.system.domain.SysDictItemDomain;
import com.hiss.basic.model.system.request.SysDictItemCreateRequest;
import com.hiss.basic.model.system.request.SysDictItemQueryRequest;
import com.hiss.basic.model.system.request.SysDictItemUpdateRequest;
import com.hiss.basic.model.system.response.SysDictItemQueryResponse;
import com.hiss.basic.starter.cache.annotation.CacheExpire;
import com.hiss.basic.starter.cache.constant.CacheConstant;
import com.hiss.basic.starter.core.exception.BusinessException;
import com.hiss.basic.starter.core.helper.MapstructHelper;
import com.hiss.basic.starter.core.helper.ValidationHelper;
import com.hiss.basic.starter.mybatis.utils.PageUtils;
import com.hiss.basic.system.mapper.SysDictItemMapper;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * 系统字典 service impl
 */
@Slf4j
@Service
@CacheConfig(cacheNames = CacheConstant.SYS_DICT_ITEM_KEY)
public class SysDictItemServiceImpl extends ServiceImpl<SysDictItemMapper, SysDictItemDomain> implements ISysDictItemService {

    @Resource
    private ISysDictService sysDictService;

    @Override
    @CacheExpire(60 * 60 * 3)
    @Cacheable(key = "#dictCode", unless = "#result == null || #result.size() == 0")
    public List<SysDictItemQueryResponse> findList(String dictCode) {
        if (StrUtil.isNotBlank(dictCode)) {
            SysDictDomain dict = sysDictService.findByCode(dictCode);
            if (ObjectUtil.isNotNull(dict)) {
                QueryWrapper wrapper = new QueryWrapper();
                wrapper.eq(SysDictItemDomain::getDictId, dict.getId());
                wrapper.orderBy(SysDictItemDomain::getSort, false);
                wrapper.orderBy(SysDictItemDomain::getCreateTime, false);
                return listAs(wrapper, SysDictItemQueryResponse.class);
            }
        }
        return ListUtil.toList();
    }

    @Override
    public Page<SysDictItemQueryResponse> findPageList(SysDictItemQueryRequest request) {
        QueryWrapper wrapper = new QueryWrapper();
        if (ObjectUtil.isNotNull(request)) {
            wrapper.eq(SysDictItemDomain::getDictId, request.getDictId(), ObjectUtil.isNotNull(request.getDictId()));
            wrapper.eq(SysDictItemDomain::getEnableStatus, request.getEnableStatus(), ObjectUtil.isNotNull(request.getEnableStatus()));
            wrapper.like(SysDictItemDomain::getLabel, request.getLabel(), StrUtil.isNotBlank(request.getLabel()));
        }
        wrapper.orderBy(SysDictItemDomain::getSort, false);
        wrapper.orderBy(SysDictItemDomain::getCreateTime, false);
        Page page = PageUtils.getPage();
        return pageAs(page, wrapper, SysDictItemQueryResponse.class);
    }

    @Override
    @CacheEvict(allEntries = true)
    public void create(SysDictItemCreateRequest request) {
        ValidationHelper.validate(request);
        long count = QueryChain.of(SysDictItemDomain.class)
                .eq(SysDictItemDomain::getDictId, request.getDictId())
                .eq(SysDictItemDomain::getValue, request.getValue())
                .count();
        if (count > 0) {
            throw new BusinessException("字典项键值已存在");
        }
        SysDictItemDomain domain = MapstructHelper.convert(request, SysDictItemDomain.class);
        save(domain);
    }

    @Override
    @CacheEvict(allEntries = true)
    public void update(SysDictItemUpdateRequest request) {
        ValidationHelper.validate(request);
        long count = QueryChain.of(SysDictItemDomain.class)
                .eq(SysDictItemDomain::getDictId, request.getDictId())
                .eq(SysDictItemDomain::getValue, request.getValue())
                .ne(SysDictItemDomain::getId, request.getId())
                .count();
        if (count > 0) {
            throw new BusinessException("字典项键值已存在");
        }
        SysDictItemDomain domain = MapstructHelper.convert(request, SysDictItemDomain.class);
        updateById(domain);
    }

    @Override
    @CacheEvict(allEntries = true)
    public void remove(Long id) {
        removeById(id);
    }

    @Override
    @CacheEvict(allEntries = true)
    public void removeByDictId(Long dictId) {
        if (ObjectUtil.isNull(dictId)) {
            throw new BusinessException("字典 ID 不能为空");
        }
        remove(QueryWrapper.create().where(SysDictItemDomain::getDictId).eq(dictId));
    }
}
